package com.fingard.dsp.bank.directbank.bocom01;

import static com.fingard.io.FileHelper.existFile;
import static com.fingard.io.FileHelper.readFileText;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.threading.ThreadPoolUtil;
import com.fingard.util.SmbFileUtil;
import com.fingard.util.ZipHelper;

public class BOCOM01SyncTask extends BOCOM01Base {

    private String actNum = "";
    private String dateFrom = "";
    private String dateTo = "";
    private String actCur = "";
    private String receiptSaveToMainDir = "";

    public static ArrayList<String[]> getTextArray(String content,String splitChar){
        ArrayList<String[]> retStrArr = new ArrayList<String[]>();
        String[] h_content = content.split("\r\n");
        for(String s : h_content){
            String column[] = s.split(splitChar);
            retStrArr.add(column);
        }
        return retStrArr;
    }

    public BOCOM01SyncTask(String p_actNum, String p_actCur, String p_dateFrom, String p_dateTo) {
        actNum = p_actNum;
        actCur = p_actCur;
        dateFrom = p_dateFrom;
        dateTo = p_dateTo;
    }

    public void downloadReceipt() {
        ThreadPoolUtil.execute(new Runnable() {
            @Override
            public void run() {
                StringBuilder logSb = new StringBuilder();
                try {
                    setSbLog(logSb);
                    receiptSaveToMainDir = FGBiz.dspCenter.dspSet.receiptMainDir;
                    if (!StringHelper.isNullOrEmpty(receiptSaveToMainDir)) {
                        if (!StringHelper.isNullOrEmpty(FGBiz.dspCenter.dspSet.receiptShareDir)) {
                            if (!StringHelper.isNullOrEmpty(FGBiz.dspCenter.dspSet.receiptPushServerUrl)) {
                                pushReceiptToATS();
                            } else {
                                WriteBankLogLn("DSPSystem未配置回单文件推送地址");
                            }
                        } else {
                            WriteBankLogLn("DSPSystem未配置回单文件共享目录");
                        }
                    } else {
                        WriteBankLogLn("DSPSystem未配置回单文件下载保存主目录");
                    }
                } catch (Exception e) {
                    WriteBankLogLn(e);
                }
            }
        });
    }

    private void pushReceiptToATS() {
        StringBuilder logSb = new StringBuilder();
        String tmpDateFileDir = getTempFileDirectory();
        try {
            setSbLog(logSb);
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(Format.Date8Format.parse(dateFrom));

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(Format.Date8Format.parse(dateTo));

            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            boolean isDown = true;

            //按自然日循环查询
            while (tmpIntDateFrom <= tmpIntDateTo) {
                String recordPath = FGBiz.DSPHOME_Parent + File.separator + "ReceiptRecordData.txt";
                String localSumFilePath = getTempFileDirectory() + File.separator + "SumFile" + File.separator + dateFrom + ".zip";
                boolean fileExist = false;
                StringBuilder json = new StringBuilder();
                if (getBankConfig().getValueAsBool("receiptPushHasTenantId")) {
                    json.append("tenantId=" + FGBiz.dspCenter.dspSet.tenant + "&transType=downloadreceipt&data={\"rows\":[");
                } else {
                    json.append("transType=downloadreceipt&data={\"rows\":[");
                }
                receiptSaveToMainDir = FGBiz.dspCenter.dspSet.receiptMainDir;
                // 读取文件内容判断是否已经下载过
                if (fileRead(recordPath, dateFrom)) {
                    WriteBankLogLn(String.format("查询日期：[%s]回单已完成过推送，如需重新推送请删除该日期重新执行", dateFrom));
                    tmpCalendarFrom.add(Calendar.DATE, 1);
                    tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
                    dateFrom = Format.Date8Format.format(tmpCalendarFrom.getTime());
                    fileExist = false;
                    continue;
                }
                List<File> fileList = new ArrayList<File>();
                if (isDown) {
                    FtpSet ftpSet = bankFront.getFtpSet("receipt");
                    if ("FTPDOWNLOAD".equals(bankFront.getStrValueByFor("receiptDownLoadType", ""))) {
                        System.out.println("开始执行下载文件。。。。");
                        String downFilePath = ftpSet.downDir;
                        WriteBankLogLn("FTP下载地址" + ftpSet.serverIP + ":" + ftpSet.port);
                        WriteBankLogLn("开始下载服务器文件" + downFilePath + "至本地文件" + receiptSaveToMainDir);
                        FtpPortClient ftpPtClient = new FtpPortClient(ftpSet);
                        ftpPtClient.connect();
                        ftpPtClient.list(downFilePath, ".zip");
                        ArrayList<String> ftpFileList = ftpPtClient.arFiles;
                        String fileStr = dateFrom;
                        StringBuilder fileNameStr = new StringBuilder();
                        for (int i = 0; i < ftpFileList.size(); i++) {
                            String ftpFileName = ftpFileList.get(i);
                            if (ftpFileName.contains("_" + fileStr) && ftpFileName.contains(".zip")) {
                                FtpReceiver tmpReceiver = ftpPtClient.downloadFile(ftpFileName,
                                        receiptSaveToMainDir + ftpFileName.substring(ftpFileName.lastIndexOf("/"), ftpFileName.length()));
                                if (tmpReceiver.connState.length() == 0 && tmpReceiver.isCompleted) {
                                    File file = new File(receiptSaveToMainDir + ftpFileName.substring(ftpFileName.lastIndexOf("/"), ftpFileName.length()));
                                    fileList.add(file);
                                    fileNameStr.append(file.getName());
                                }
                            }
                        }
                        WriteBankLogLn("FTP下载服务器文件成功：" + fileList.size() + "笔至本地文件" + receiptSaveToMainDir
                                + "，下载的文件名称为：" + fileNameStr.toString());
                    } else {
                        File tmpFile = new File(localSumFilePath);
                        if (tmpFile.exists()) {
                            WriteBankLogLn(String.format("针对账号：[%s]，查询日期：[%s]汇总文件已存在无需再次下载", actNum, dateFrom));
                            fileExist = true;
                        }
                        //FTP下载
                        List<String> fileNames = new ArrayList<String>();
                        FtpPortClient ftpPtClient = new FtpPortClient(ftpSet);
                        try {
                            System.out.println("开始连接FTP。。。。");
                            //开启被动传输
                         /*   if (this.getBankConfig().getValueAsBool("ftpConnectType")) {
                                ftpPtClient.setLocalPassiveMode();
                            }*/
                            ftpPtClient.connect();
                            ftpPtClient.list(ftpSet.downDir,".zip");
                            fileNames = ftpPtClient.arFiles;
                            System.out.println("连接FTP正常，遍历到的文件为："+ fileNames);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (fileNames != null) {
                            System.out.println("下载到的文件："+fileNames);
                            //根据日期匹配要下载的文件
                            for (String f : fileNames) {
                                if (f.contains(dateFrom)) {
                                    FtpReceiver tmpReceiver = ftpPtClient.downloadFile(f, localSumFilePath);
                                    WriteBankLogLn("ftp下载信息：" + tmpReceiver.connMsg);
                                    if (tmpReceiver.isCompleted) {
                                        fileExist = true;
                                        WriteBankLogLn(String.format("针对账号：[%s]，查询日期：[%s]下载汇总文件成功", actNum, dateFrom));
                                        WriteBankLogLn("下载的文件名：" + f);
                                    } else {
                                        WriteBankLogLn(String.format("针对账号：[%s]，查询日期：[%s]下载汇总文件失败，失败原因：[%s]", actNum, dateFrom, tmpReceiver.connMsg));
                                    }
                                }
                            }
                        }
                    }
                }
                //测试
        //        localSumFilePath = "E:\\直联银行\\光大银行\\0115680176984198_20200309.zip";
        //        fileExist = true;



                int tmpFileCount = 0;
                boolean isSaveOnlyFile = false;
                if (fileExist) {
                    System.out.println("下载到本地的文件名称为：" + localSumFilePath);
                    WriteBankLogLn("下载到本地的文件名称为：" + localSumFilePath);
                    boolean isZip = true;
                    File fileZip = new File(localSumFilePath);
                    String fileName = fileZip.getName();
                    String actNum = null;
                    String tranDate = null;
                    if (fileZip.exists()) {
                        ZipHelper.unzipFile(fileZip.getPath(), tmpDateFileDir);
                        String dataPath = tmpDateFileDir + File.separator + fileZip.getName().replace(".zip", "");
                        // 再次解压
                        WriteBankLogLn("解压至：" + dataPath);
                        File receiptDir = new File(dataPath);
                        File[] filep = receiptDir.listFiles();
                        for (File f : filep) {
                            if (f.getName().contains(".zip")) {
                                WriteBankLogLn(Thread.currentThread().getName() + "正在执行。。。");
                                ZipHelper.unzipFile(f.getPath(), f.getParent());
                                String fpath = f.getPath().replace(".zip", "");
                                File f_s = new File(fpath);
                                File[] receiptFiles = f_s.listFiles();
                                if (receiptFiles != null && receiptFiles.length > 0) {
                                    WriteBankLogLn(f.getName() + "解压后共有" + receiptFiles.length + "个文件");
                                    // String actCur = fileName.split("_")[3];
                                    for (File receiptFile : receiptFiles) {
                                        if (receiptFile.exists() && receiptFile.getName().contains("+")) {
                                            File newFile = new File(receiptFile.getPath().replace("+", "_"));
                                            if (!receiptFile.renameTo(newFile)) {
                                                WriteBankLogLn("解压后pdf文件名称为：" + receiptFile.getPath() + ",修改文件名称出错");
                                                continue;
                                            } else {
                                                receiptFile = newFile;
                                            }
                                        }
                                        if (!receiptFile.getName().contains(".pdf")) {
                                            continue;
                                        }
                                        String tmpByDate = dateFrom;
                                        String[] receiptFileName = receiptFile.getName().split("_");
                                        actNum = f.getName().split("_")[0];
                                        String actCur = getBankConfig().getMapValueByKey("elereceiptAccountInfo",
                                                actNum);
                                        if (StringHelper.isNullOrEmpty(actCur)) {
                                            actCur = "1";
                                        }
                                        tmpByDate = tmpByDate.substring(0, 6) + "/" + tmpByDate.substring(6, 8) + "/"
                                                + reqHeader.bankCode + "/" + actNum + "/";
                                        tranDate = receiptFileName[0];
                                        String collect_txt = receiptFile.getParent() + File.separator + f.getName().replace(".zip", "") + ".txt";
                                        Map<String, String[]> data = new ConcurrentHashMap<String, String[]>();
                                        //回单编号去匹配
                                        String receiptCode = receiptFileName[1];
                                        int curFieldNum = 13;
                                        if (existFile(collect_txt)) {
                                            WriteBankLogLn("开始匹配汇总文件:" + collect_txt);
                                            String fileContent = new String();
                                            fileContent = readFileText(collect_txt, "UTF-8");

                                            if (StringHelper.hasAnyChar(this.getBankConfig().getValueAsString("useNewReponsetxt"))) {
                                                curFieldNum = Integer.valueOf(this.getBankConfig().getValueAsString("useNewReponsetxt")) - 1;
                                            }

                                            StringBuilder curSbLog = new StringBuilder();
                                            ArrayList<String[]> curDataList = getTextArray(fileContent, "\\|!");
                                            if (curSbLog.length() == 0) {
                                                //回单日期|!回单编号|!会计流水号|!序号|!付款人账号|!付款人户名|!收款人账号|!收款人户名|!交易金额|!借贷标志|!摘要|!附加信息
                                                for (int j = 1; j < curDataList.size(); j++) {
                                                    //匹配会计流水号
                                                    String[] curRowDataArr = curDataList.get(j);
                                                    String tranSeqNo = curRowDataArr[1];
                                                    if (tranSeqNo.equals(receiptCode)) {
                                                        data.put(receiptCode, curRowDataArr);
                                                        WriteBankLogLn("成功匹配到回单pdf,回单编号：" + receiptCode);
                                                    }
                                                }
                                            } else {
                                                WriteBankLogLn("匹配汇总文件失败:" + curSbLog.toString());
                                            }
                                        }
                                        // 上传文件到共享目录下
                                        int result = -1;
                                        WriteBankLogLn("正在上传文件至共享目录:" + FGBiz.dspCenter.dspSet.receiptShareDir);
                                        if (receiptFile.exists()) {
                                            result = SmbFileUtil.smbUploading(receiptFile.getPath(), tmpByDate,
                                                    FGBiz.dspCenter.dspSet.receiptShareDir);
                                        }
                                        if (result == 0 || result == 1) {
                                            isSaveOnlyFile = true;
                                            tmpFileCount++;
                                            if (result == 0) {
                                                WriteBankLogLn("文件上传成功");
                                            } else {
                                                WriteBankLogLn("文件已存在共享目录无需重复上传");
                                            }
                                            // 推送数据给ATS处理
                                            String[] receiptData = data.get(receiptCode);
                                            if (receiptData == null) {
                                                WriteBankLogLn("根据回单编号：" + receiptCode + "未匹配到回单信息");
                                                break;
                                            }
                                            String moneyway = receiptData[curFieldNum - 2].equals("借方") ? "1" : "2";
                                            json.append("{");
                                            json.append("\"actNum\":\"" + actNum + "\",");
                                            json.append("\"actCur\":\"" + actCur + "\",");
                                            json.append("\"receiptCode\":\"" + receiptFileName[1] + "\",");// 回单编号
                                            json.append("\"receiptType\":\"" + "" + "\",");// 回单类型 // 1：存款回单；2：取款回单；3：转账回单；4：缴税回单；5：收费回单；6定期回单；7：活期回单
                                            json.append("\"receiptState\":\"" + "" + "\",");// 回单状态  // 1：正常；2：冲正；3：被冲正；4：当日冲正
                                            json.append("\"oppActName\":\"" + URLEncoder.encode(receiptData[curFieldNum - 4], "GBK") + "\",");
                                            json.append("\"oppActNum\":\"" + receiptData[curFieldNum - 5] + "\",");
                                            json.append("\"amount\":\"" + receiptData[curFieldNum - 3] + "\",");
                                            json.append("\"moneyway\":\"" + moneyway + "\",");
                                            json.append("\"tranSeqNo\":\"" + receiptData[2] + "\",");
                                            json.append("\"tranCode\":\"" + "" + "\",");// 交易码?
                                            json.append("\"tranDate\":\"" + Format.Date10Format.format(Format.Date8Format.parse(tranDate)) + "\",");
                                            json.append("\"filePath\":\"" + tmpByDate + receiptFile.getName() + "\",");// 回单文件仓库存储路径
                                            json.append("\"fileType\":\"1\"");
                                            json.append("},");
                                        } else {
                                            WriteBankLogLn("上传文件至共享目录失败，请检查共享目录配置是否正确");
                                        }
                                        if (FileHelper.deleteFileIfExists(receiptFile.getPath())) {
                                            WriteBankLogLn("已删除临时文件：" + receiptFile.getPath());
                                        }
                                    }
                                }
                                if (delFile(new File(f.getPath().replace(".zip", "")))) {
                                    WriteBankLogLn("已删除解压后的临时文件：" + f.getPath().replace(".zip", ""));
                                } else {
                                    WriteBankLogLn(fileName + "解压后文件为空");
                                }
                            }
                        }
                        if (isZip) {
                            String filePath = receiptSaveToMainDir + File.separator + actNum + File.separator + tranDate
                                    + File.separator;
                            if (isSaveOnlyFile) {
                                Calendar calendar = Calendar.getInstance();
                                calendar.setTime(new Date());
                                calendar.add(Calendar.DAY_OF_MONTH, -2);
                                if (Format.Date8Format.parse(tranDate).before(calendar.getTime())) {
                                    FileHelper.writeFile(filePath + actNum + "_" + tranDate + ".txt", "", getCharset());
                                }
                            }
                        }
                    } else {
                        WriteBankLogLn(String.format("查询日期：[%s]无回单文件", dateFrom));
                    }
                    if (tmpFileCount > 0) {
                        json.deleteCharAt(json.length() - 1);
                        json.append("]}");
                        WriteBankLogLn("推送数据到ATS的数据为：" + json.toString());
                        String[] data = sendToATS(json.toString());
                        if (data[0].length() == 0 && data[1].equals("ok")) {
                            WriteBankLogLn("推送数据到ATS成功,请查看数据");
                        } else {
                            WriteBankLogLn("推送数据到ATS失败");
                        }
                    } else {
                        WriteBankLogLn("成功保存文件条数为0，不需要推送数据到ATS");
                    }
                }
                StringBuilder datelog = new StringBuilder();
                datelog.append(dateFrom);
                datelog.append("|");
                writeFile(recordPath, datelog.toString());
                tmpCalendarFrom.add(Calendar.DATE, 1);
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
                dateFrom = Format.Date8Format.format(tmpCalendarFrom.getTime());
            }
        } catch (Exception e) {
            WriteBankLogLn(e);
        } finally {
            if (delFile(new File(tmpDateFileDir))) {
                WriteBankLogLn("临时文件已全部删除：" + tmpDateFileDir);
            }
            try {
                String tmpDateDir = Format.DateForLogFormat.format(new Date()).replace("-", File.separator);
                String tmpSubFileName = FGBiz.dspCenter.bankLogsFirstDir + File.separator + tmpDateDir + File.separator + "BOCOM01" + File.separator + "SyncTask-downloadReceipt" + "_" + actNum + "_" + Format.DateTime17Format.format(new Date()) + "_" + UUID.randomUUID() + ".txt";
                String tmpLogFile = FGBiz.dspCenter.bankLogsDirPath + File.separator + tmpSubFileName;
                FileHelper.writeFile(tmpLogFile, logSb);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    static boolean delFile(File file) {
        if (!file.exists()) {
            return false;
        }

        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                delFile(f);
            }
        }
        return file.delete();
    }

    public static boolean fileRead(String filePath, String chars) throws Exception {
        File file = new File(filePath);
        if (file.exists()) {
            FileReader reader = new FileReader(file);
            BufferedReader bReader = new BufferedReader(reader);
            StringBuilder sb = new StringBuilder();
            String s = "";
            while ((s = bReader.readLine()) != null) {
                sb.append(s);
            }
            bReader.close();
            String str = sb.toString();
            return str.contains(chars);
        }
        return false;
    }

    /**
     * 将字符串追加到文件已有内容后面
     *
     * @param fileFullPath 文件完整地址：D:/test.txt
     * @param content      需要写入的
     */
    public static void writeFile(String fileFullPath, String content) {
        FileOutputStream fos = null;
        try {
            File tmpFile = new File(fileFullPath);
            File parentDir = new File(tmpFile.getParent());
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }
            if (!tmpFile.exists()) {
                tmpFile.createNewFile();
            }
            //true不覆盖已有内容
            fos = new FileOutputStream(fileFullPath, true);
            //写入
            fos.write(content.getBytes());
            // 写入一个换行
            fos.write("\r\n".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
